package org.yuezejian.alarm.netty.channel;

import io.netty.channel.socket.nio.NioDatagramChannel;
import org.yuezejian.alarm.netty.enums.ClientType;
import org.yuezejian.alarm.netty.handler.AbstractClientHandler;
import org.yuezejian.alarm.netty.handler.ClientHandlerFactory;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.socket.DatagramPacket;
import io.netty.handler.codec.MessageToMessageDecoder;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.nio.charset.Charset;
import java.util.List;

/**
 * 自定义UDP ChannelInitializer
 *
 * @author yuezejian
 * @since 2024.8.1
 */
@Slf4j
@Component
public class UDPCustomChannelInitializer extends ChannelInitializer<NioDatagramChannel> {

    @Autowired
    private ClientHandlerFactory clientHandlerFactory;

    private ClientType clientType; // 协议类型
    private String handlerType; // 处理器类型

    // 设置协议类型和处理器类型的方法
    public void setClientType(ClientType clientType) {
        this.clientType = clientType; // 设置协议类型
    }

    public void setHandlerType(String handlerType) {
        this.handlerType = handlerType; // 设置处理器类型
    }

    @Override
    protected void initChannel(NioDatagramChannel ch) throws Exception {
        if (handlerType == null) {
            throw new IllegalArgumentException("Protocol type and handler type cannot be null");
        }

        ChannelPipeline pipeline = ch.pipeline();

        pipeline.addLast("framer", new MessageToMessageDecoder<DatagramPacket>() {
            @Override
            protected void decode(ChannelHandlerContext ctx, DatagramPacket msg, List<Object> out) throws Exception {
                out.add(msg.content().toString(Charset.forName("UTF-8")));
            }
        });

        // 使用工厂创建相应的 ClientHandler
        AbstractClientHandler handler = clientHandlerFactory.createHandler(handlerType);
        if (handler != null) {
            pipeline.addLast(handler); // 将处理器添加到管道中
        } else {
            throw new IllegalStateException("Failed to create handler for type: " + handlerType);
        }
    }
}
